package com.k12.common.util;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.regex.Pattern;

/**
 * 密码加密工具类
 * 使用BCrypt算法实现密码加密和验证
 */
public class PasswordUtils {

    private static final PasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
    
    // BCrypt加密后的密码格式校验正则
    private static final Pattern BCRYPT_PATTERN = Pattern.compile("\\A\\$2[ayb]?\\$(\\d\\d)\\$[./0-9A-Za-z]{53}");
    
    /**
     * 加密原始密码
     * @param rawPassword 原始密码
     * @return 加密后的密码
     * @throws IllegalArgumentException 如果原始密码为空
     */
    public static String encode(String rawPassword) {
        if (StringUtils.isBlank(rawPassword)) {
            throw new IllegalArgumentException("原始密码不能为空");
        }
        return PASSWORD_ENCODER.encode(rawPassword);
    }
    
    /**
     * 验证密码是否匹配
     * @param rawPassword 原始密码
     * @param encodedPassword 加密后的密码
     * @return 匹配返回true，否则false
     * @throws IllegalArgumentException 如果任一参数为空
     */
    public static boolean matches(String rawPassword, String encodedPassword) {
        if (StringUtils.isBlank(rawPassword) || StringUtils.isBlank(encodedPassword)) {
            throw new IllegalArgumentException("密码参数不能为空");
        }
        return PASSWORD_ENCODER.matches(rawPassword, encodedPassword);
    }
    
    /**
     * 检查字符串是否是BCrypt加密格式
     * @param encodedPassword 待检查的密码字符串
     * @return 如果是BCrypt格式返回true
     */
    public static boolean isBCryptFormat(String encodedPassword) {
        if (StringUtils.isBlank(encodedPassword)) {
            return false;
        }
        return BCRYPT_PATTERN.matcher(encodedPassword).matches();
    }
    
    /**
     * 生成随机密码
     * @param length 密码长度(8-32)
     * @return 随机密码
     */
    public static String generateRandomPassword(int length) {
        if (length < 8 || length > 32) {
            throw new IllegalArgumentException("密码长度必须在8-32之间");
        }
        
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+";
        StringBuilder sb = new StringBuilder();
        
        for (int i = 0; i < length; i++) {
            int index = (int) (Math.random() * chars.length());
            sb.append(chars.charAt(index));
        }
        
        return sb.toString();
    }
    
    /**
     * 密码强度检查
     * @param password 待检查的密码
     * @return 强度等级 (1-4)
     */
    public static int checkPasswordStrength(String password) {
        if (StringUtils.isBlank(password)) {
            return 0;
        }
        
        int strength = 0;
        
        // 长度检查
        if (password.length() >= 8) strength++;
        if (password.length() >= 12) strength++;
        
        // 包含数字
        if (password.matches(".*\\d.*")) strength++;
        
        // 包含小写字母
        if (password.matches(".*[a-z].*")) strength++;
        
        // 包含大写字母
        if (password.matches(".*[A-Z].*")) strength++;
        
        // 包含特殊字符
        if (password.matches(".*[!@#$%^&*()_+].*")) strength++;
        
        return Math.min(strength, 4);
    }
}